package com.dh.leetcode.k1;

import com.dh.leetcode.common.TreeNode;
import com.dh.leetcode.common.TreeNodeIterator;
import org.junit.Assert;
import org.junit.Test;

import java.util.LinkedList;
import java.util.Queue;

/**
 * ClassName: _1609_even_odd_tree
 *
 * @author shouzimu
 * @Description: 1609. 奇偶树
 * 如果一棵二叉树满足下述几个条件，则可以称为 奇偶树 ：
 * <p>
 * 二叉树根节点所在层下标为 0 ，根的子节点所在层下标为 1 ，根的孙节点所在层下标为 2 ，依此类推。
 * 偶数下标 层上的所有节点的值都是 奇 整数，从左到右按顺序 严格递增
 * 奇数下标 层上的所有节点的值都是 偶 整数，从左到右按顺序 严格递减
 * 给你二叉树的根节点，如果二叉树为 奇偶树 ，则返回 true ，否则返回 false 。
 * <p>
 * <p>
 * <p>
 * 示例 1：输入：root = [1,10,4,3,null,7,9,12,8,6,null,null,2]
 * 输出：true
 * 解释：每一层的节点值分别是：
 * 0 层：[1]
 * 1 层：[10,4]
 * 2 层：[3,7,9]
 * 3 层：[12,8,6,2]
 * 由于 0 层和 2 层上的节点值都是奇数且严格递增，而 1 层和 3 层上的节点值都是偶数且严格递减，因此这是一棵奇偶树。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/even-odd-tree
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * @date 2021/12/25 08:25
 */
public class _1609_even_odd_tree {


    /**
     * 广度优先搜索/按层遍历
     *
     * @param root
     * @return
     */
    public boolean isEvenOddTree(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        int level = 1;
        while (!queue.isEmpty()) {
            int size = queue.size();
            TreeNode preValue = null;
            for (int i = 0; i < size; i++) {
                TreeNode treeNode = queue.poll();
                if (treeNode.val % 2 != level % 2) {
                    return false;
                }
                if (null == preValue) {
                    preValue = treeNode;
                } else {
                    if (level % 2 == 1 && preValue.val >= treeNode.val) {
                        return false;
                    }

                    if (level % 2 == 0 && preValue.val <= treeNode.val) {
                        return false;
                    }
                    preValue = treeNode;
                }
                if (null != treeNode.left) {
                    queue.add(treeNode.left);
                }
                if (null != treeNode.right) {
                    queue.add(treeNode.right);
                }
            }
            level++;
        }
        return true;
    }

    @Test
    public void isEvenOddTreeTest() {
        TreeNode treeNode = TreeNodeIterator.initTestTree(new Integer[]{1, 10, 4, 3, null, 7, 9, 12, 8, 6, null, null, 2});
        Assert.assertEquals(treeNode, isEvenOddTree(treeNode));
    }

}
